﻿local SpawnPoint        = {}
local PlayersObjects    = {}
local Objects           = {}
local PlayersStarted    = {}
local Players           = {}

local isMapRunning = false
local mapResource  = nil

-- Credis:
--   - Resources:
--       • vick for the laserpointer.
--       • erorr404 for the editor.
--		 • jbeta for the editor.
--		 • Talidan for the editor.
--   - Maps:
--       • Ransom for the map (gmods-main).
--       


-- Functions --
local _getPlayerName = getPlayerName

function getPlayerName(target)
	return string.gsub(_getPlayerName(target), '#%x%x%x%x%x%x', '' )
end

function getMapTable()
	local tablemaps = {}
	local maps = 0
	for _, resource in ipairs(getResources()) do
		if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
			table.insert(tablemaps, resource)
			maps = maps + 1
		end
	end
	if maps == 0 then
		return nil
	else
		return tablemaps
	end
end

function getMapRunning()
	if isMapRunning then
		return true
	else
		return false
	end
end

function getRandomMap()
	local tablemaps = {}
	local maps = 0
	for _, resource in ipairs(getResources()) do
		if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
			table.insert(tablemaps, resource)
			maps = maps + 1
		end
	end
	if maps == 0 then
		outputChatBox("ERROR: Gamemode doesn't have any maps.", getRootElement(), 255, 0, 0)
		outputChatBox("ERROR: Download maps from site, after do /refresh.", getRootElement(), 255, 0, 0)
	else
		return tablemaps[math.random(1, #tablemaps)]
	end
end

function getMap()
	for _, resource in ipairs(getResources()) do
		if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
			if getResourceState(resource) == "running" then return resource end
		end
	end
	return nil
end

function setMap(map)
	if getMap() == map then
		restartResource(map)
	else
		for _, resource in ipairs(getResources()) do
			if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
				if getResourceState(resource) == "running" then stopResource(resource) end
			end
		end
		if getResourceInfo(map, "type") == "map" and getResourceInfo(map, "gamemodes") == "gmods" then
			isMapRunning = false
			startResource(map)
		end
	end
end

function getMapName()
	for _, resource in ipairs(getResources()) do
		if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
			if getResourceState(resource) == "running" then
				return getResourceInfo(resource, "name") or ""
			end
		end
	end
	return nil
end

function isPlayerDownloading(target)
	for i, v in ipairs(Players) do
		if v == target then
			return false
		end
	end
	return true
end

function addPlayerStarted(target)
	table.insert(PlayersStarted, target)
end

function isPlayerStarted(target)
	for i, v in ipairs(PlayersStarted) do
		if v == target then
			return true
		end
	end
	return false
end
---------------

function onResourceStart()
	local maps = 0
	showPlayerHudComponent(getRootElement(), "all", false)
	showPlayerHudComponent(getRootElement(), "crosshair", true)
	setWeaponProperty(24, "pro", "maximum_clip_ammo", 10000)
	for _, player in ipairs(getElementsByType("player")) do
		setCameraTarget(player, player)
		fadeCamera(player, false, 0)
		giveWeapon(player, 24, 10000, true)
		setWeaponAmmo(player, 24, 10000)
		toggleControl(player, "fire", false)
	end
	for _, resource in ipairs(getResources()) do
		if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
			maps = maps + 1
		end
	end
	if maps == 0 then
		outputChatBox("ERROR: Gamemode doesn't have any maps.", getRootElement(), 255, 0, 0)
		outputChatBox("ERROR: Download maps from site, after do /refresh.", getRootElement(), 255, 0, 0)
		isMapRunning = false
	else
		setTimer(onRandomMap, 1000, 1)
	end
		
	--createObject(8546, 5705.2084960938, -1716.1893310547, -2)
end
addEventHandler("onResourceStart", getResourceRootElement(getThisResource()), onResourceStart)

function onPlayerDownloaded(source)
	if not isElement(source) then return end
	table.insert(Players, source)
	setTimer(onPlayerSpawn, 1000, 1, source)
end
addEvent("onPlayerDownloaded", true)
addEventHandler("onPlayerDownloaded", getRootElement(), onPlayerDownloaded)

function onPlayerJoin()
	outputChatBox("Welcome to our server, be invite your friend!", source, 0, 255, 0)
	fadeCamera(source, false)
end
addEventHandler("onPlayerJoin", getRootElement(), onPlayerJoin)

function onPlayerDied()
	if isMapRunning and not isPlayerDownloading(source) then
		setTimer(spawnPlayer, 2000, 1, source, unpack(SpawnPoint[math.random(1, #SpawnPoint)]))
	end
end
addEventHandler("onPlayerWasted", getRootElement(), onPlayerDied)

function onPlayerSpawn(target)
	if not isMapRunning then return end
	if target then
		if not isPlayerStarted(target) then
			if not isPlayerDownloading(target) then
				if isPedDead(target) then
					spawnPlayer(target, unpack(SpawnPoint[math.random(1, #SpawnPoint)]))
				else
					setElementPosition(target, unpack(SpawnPoint[math.random(1, #SpawnPoint)]))
				end
				showPlayerHudComponent(target, "all", false)
				showPlayerHudComponent(target, "crosshair", true)
				giveWeapon(target, 24, 10000, true)
				setWeaponAmmo(target, 24, 10000)
				toggleControl(target, "fire", false)
				setCameraTarget(target, target)
				fadeCamera(target, true)
				addPlayerStarted(target)
			end
		end
	else
		for _, player in ipairs(Players) do
			if not isPlayerStarted(player) then
				if not isPlayerDownloading(player) then
					if isPedDead(player) then
						spawnPlayer(player, unpack(SpawnPoint[math.random(1, #SpawnPoint)]))
					else
						setElementPosition(player, unpack(SpawnPoint[math.random(1, #SpawnPoint)]))
					end
					showPlayerHudComponent(player, "all", false)
					showPlayerHudComponent(player, "crosshair", true)
					giveWeapon(player, 24, 10000, true)
					setWeaponAmmo(player, 24, 10000)
					toggleControl(player, "fire", false)
					setCameraTarget(player, player)
					fadeCamera(player, true)
					addPlayerStarted(player)
				end
			end
		end
	end
end

function onResourceStartMap(resource)
	if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
		if mapResource == nil then mapResource = resource else stopResource(mapResource) end
		for _, object in ipairs(getElementsByType("object")) do
			destroyElement(object)
		end
		local meta = xmlLoadFile(":" .. getResourceName(resource) .. "/meta.xml")
		if meta then
			local filemap = xmlFindChild(meta, "map", 0)
			if filemap then
				local filename = xmlNodeGetAttribute(filemap, "src")
				if filename then
					local map = xmlLoadFile(":" .. getResourceName(resource) .. "/" .. filename)
					if map then
						for i, v in ipairs(xmlNodeGetChildren(map)) do
							if xmlNodeGetName(v) == "spawnpoint" then
								local posX     = xmlNodeGetAttribute(v, "posX")
								local posY     = xmlNodeGetAttribute(v, "posY")
								local posZ     = xmlNodeGetAttribute(v, "posZ")
								local rotation = xmlNodeGetAttribute(v, "rotation")
								table.insert(SpawnPoint, {posX, posY, posZ, rotation})
							elseif xmlNodeGetName(v) == "object" then
								local posX  = xmlNodeGetAttribute(v, "posX")
								local posY  = xmlNodeGetAttribute(v, "posY")
								local posZ  = xmlNodeGetAttribute(v, "posZ")
								local rotX  = xmlNodeGetAttribute(v, "rotX")
								local rotY  = xmlNodeGetAttribute(v, "rotY")
								local rotZ  = xmlNodeGetAttribute(v, "rotZ")
								local model = xmlNodeGetAttribute(v, "model")
								table.insert(Objects, createObject(model, posX, posY, posZ, rotX, rotY, rotZ))
							end
						end
						isMapRunning = true
					else
						outputChatBox("ERROR: Doesn't exists file '" .. filename .. "' in '" .. getResourceName(resource) .. "'.", getRootElement(), 255, 0, 0)
						outputChatBox("ERROR: The gamemode will be start random map.", getRootElement(), 255, 0, 0)
						isMapRunning = false
						onRandomMap()
					end		
					xmlUnloadFile(map)
				end
			end
		else
			outputChatBox("ERROR: Doesn't exists file 'meta.xml' in '" .. getResourceName(resource) .. "'.", getRootElement(), 255, 0, 0)
			outputChatBox("ERROR: The gamemode will be start random map.", getRootElement(), 255, 0, 0)
			isMapRunning = false
			onRandomMap()
		end
		xmlUnloadFile(meta)
		if not SpawnPoint or #SpawnPoint == 0 then return end
		setTimer(onPlayerSpawn, 1000, 1)
	end
end
addEventHandler("onResourceStart", getRootElement(), onResourceStartMap)

function onRandomMap()
	local tablemaps = {}
	local randommap
	PlayersStarted = {}
	SpawnPoint = {}
	local maps = 0
	for _, resource in ipairs(getResources()) do
		if getResourceInfo(resource, "type") == "map" and getResourceInfo(resource, "gamemodes") == "gmods" then
			if getResourceState(resource) == "running" then stopResource(resource) end
			table.insert(tablemaps, resource)
			maps = maps + 1
		end
	end
	if maps == 0 then
		outputChatBox("ERROR: Gamemode doesn't have any maps.", getRootElement(), 255, 0, 0)
		outputChatBox("ERROR: Download maps from site, after do /refresh.", getRootElement(), 255, 0, 0)
		isMapRunning = false
	else
		randommap = tablemaps[math.random(1, #tablemaps)]
		startResource(randommap)
		mapResource = randommap
	end
end

-- Commands --
function onPlayerCommandRandom(player, command)
	if (isObjectInACLGroup("user." .. getAccountName(getPlayerAccount(player)), aclGetGroup("Admin"))) then
		if isMapRunning then
			local randomMap = getRandomMap()
			if randomMap then
				for _, player in ipairs(Players) do
					fadeCamera(player, false, 0)
				end
				PlayersStarted = {}
				outputChatBox("Map '" .. getResourceInfo(randomMap, "name") .. "' started by " .. getPlayerName(player), getRootElement(), 255, 255, 255)
				setTimer(onPlayerSpawn, 2000, 1)
				mapResource = randomMap
				setMap(randomMap)
			end
		else
			outputChatBox("ERROR: This map is not running, so you'll have to wait.", player, 255, 0, 0)
		end
	end
end
addCommandHandler("random", onPlayerCommandRandom)
--------------

